package ybl.qianchuan;

import java.util.Map;
import java.sql.Timestamp;
import java.util.Calendar;
import java.time.Instant;

import com.alibaba.fastjson2.JSONObject;

import ybl.qianchuan.entities.AccessToken;

public class Auth {
    // 基本配置参数
    private static final QianChuanConfig QIANCHUAN_CONFIG = ConfigSingleton.getInstance();
    private static final String APP_ID = QIANCHUAN_CONFIG.getQIANCHUAN().getAPP_ID();
    private static final String APP_SECRET = QIANCHUAN_CONFIG.getQIANCHUAN().getAPP_SECRET();
    private static final String OPEN_API_URL_PREFIX = QIANCHUAN_CONFIG.getQIANCHUAN().getOPEN_API_URL_PREFIX();

    // 根据授权码获取访问_token
    public static JSONObject getAccessTokenByAuthCode(String authCode, String accessTokenName) {
        Map<String, Object> params = createParams("auth_code", authCode);
        JSONObject result = HttpRequest.post(OPEN_API_URL_PREFIX + "oauth2/access_token/", params);
        if (result.getInteger("code") == 0) {
            JSONObject data = result.getJSONObject("data");
            StoreManage.saveAccessToken(Map.of(
                    "accessTokenName", accessTokenName,
                    "accessToken", data.getString("access_token"),
                    "expiresIn", data.getInteger("expires_in"),
                    "refreshToken", data.getString("refresh_token"),
                    "refreshTokenExpiresIn", data.getInteger("refresh_token_expires_in")));
        } else {
            throw new ApiException(result.getString("message"));
        }
        return result;
    }

    // 刷新_token
    /**
     * 使用刷新令牌刷新访问令牌
     * 
     * @param accessTokenName 访问令牌名称
     * @return 返回刷新结果的JSON对象
     */
    public static void refreshToken(String accessTokenName) {
        // 获取访问令牌
        AccessToken accessToken = StoreManage.getAccessToken(accessTokenName);
        // 创建刷新令牌参数
        Map<String, Object> params = createParams("refresh_token", accessToken.getRefreshToken());
        // 发送HTTP POST请求进行刷新
        JSONObject result = HttpRequest.post(OPEN_API_URL_PREFIX + "oauth2/refresh_token/", params);
        // 获取刷新结果的JSON对象
        JSONObject data = result.getJSONObject("data");
        // 判断刷新结果是否成功
        if (result.getInteger("code") == 0) {
            // 更新访问令牌信息
            accessToken.setAccessToken(data.getString("access_token"));
            accessToken.setRefreshToken(data.getString("refresh_token"));
            accessToken.setAccessTokenExpires(data.getInteger("expires_in"));
            accessToken.setRefreshTokenExpires(data.getInteger("refresh_token_expires_in"));
            accessToken.setUpdateAt(Timestamp.from(Instant.now()));
            StoreManage.saveAccessToken(accessToken);
        } else {
            throw new ApiException(result.getString("message"));
        }
    }

    // 创建请求参数
    private static Map<String, Object> createParams(String grantType, String token) {
        return Map.of(
                "app_id", APP_ID,
                "secret", APP_SECRET,
                "grant_type", grantType,
                tokenKey(grantType), token);
    }

    // 获取请求参数的_token字段名
    private static String tokenKey(String grantType) {
        return grantType.equals("auth_code") ? "auth_code" : "refresh_token";
    }

    // 获取access_token
    public static AccessToken getAccessTokenByAccessTokenName(String accessTokenName) {
        AccessToken accessToken = StoreManage.getAccessToken(accessTokenName);
        // 判断AccessToken有没有过期
        // 将Timestamp转换为Calendar
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(accessToken.getUpdateAt().getTime());
        cal.add(Calendar.SECOND, accessToken.getRefreshTokenExpires());
        // 检查accessToken是否过期
        if (cal.before(Calendar.getInstance())) {
            return StoreManage.getAccessToken(accessTokenName);
        } else {
            refreshToken(accessTokenName);
            return StoreManage.getAccessToken(accessTokenName);
        }
    }

    // public static void main(String[] args) {
    // // 设置utf-8编码
    // System.setProperty("file.encoding", "UTF-8");
    // // bdb67b409c23f080c09bb75d742992403f7e7c3b
    // //
    // System.out.println(getAccessTokenByAuthCode("6d120cb9fc81ed06ce20acf25ad4d205f790c33f",
    // // "15618242794"));
    // ;
    // refreshToken("15618242794");
    // }
}